package com.java.common.service;

import com.java.common.constant.Constants;
import com.java.common.lang.enums.UserTypeEnum;
import com.java.common.lang.exception.user.UserPasswordRetryLimitExceedException;
import com.java.common.service.manager.AsyncManager;
import com.java.common.service.manager.factory.AsyncFactory;
import com.java.common.utils.MessageUtils;
import com.java.common.utils.StringUtils;
import com.java.common.utils.redis.RedisCache;
import com.java.module.system.domain.SysLogininfor;
import com.java.module.system.domain.dto.LogininforDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 登录密码方法
 *
 * @author Administrator
 */
@Component
public class SysPasswordService {

    @Autowired
    private RedisCache redisCache;

    @Value(value = "${user.password.maxRetryCount}")
    private int maxRetryCount;

    @Value(value = "${user.password.lockTime}")
    private int lockTime;

    public void checkLoginPwdLimitCache(String username, UserTypeEnum userType) {
        String cacheKey = getCacheKey(username, userType);
        if (!redisCache.hasKey(cacheKey)) {
            return;
        }
        Integer retryCount = redisCache.getCacheObject(cacheKey);
        if (retryCount == null) {
            return;
        }
        if (retryCount < maxRetryCount) {
            return;
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(new LogininforDTO(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, lockTime), userType, null)));
        throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime);
    }

    public void updateLoginPwdLimitCache(String username, UserTypeEnum userType) {
        String cacheKey = getCacheKey(username, userType);
        Integer retryCount = redisCache.getCacheObject(cacheKey);
        if (retryCount == null) {
            retryCount = 0;
        }
        retryCount = retryCount + 1;
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(new LogininforDTO(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.count", retryCount), userType, null)));
        redisCache.setCacheObject(cacheKey, retryCount, lockTime, TimeUnit.MINUTES);
    }

    public int clearLoginPwdLimitCache(String username, UserTypeEnum userType) {
        String cacheKey = getCacheKey(username, userType);
        if (redisCache.hasKey(cacheKey)) {
            redisCache.deleteObject(cacheKey);
            return 1;
        }
        return 0;
    }

    public int clearLoginPwdLimitCache(SysLogininfor logininfor) {
        String userName = logininfor.getUserName();
        Integer userType = logininfor.getUserType();
        if (StringUtils.isBlank(userName) || userType == null) {
            return -1;
        }
        UserTypeEnum userTypeEnum = UserTypeEnum.getUserTypeEnum(logininfor.getUserType());
        if (userTypeEnum == UserTypeEnum.UNKNOWN) {
            return -2;
        }
        return clearLoginPwdLimitCache(userName, userTypeEnum);
    }

    private String getCacheKey(String username, UserTypeEnum userType) {
        return Constants.PWD_ERR_CNT_KEY + userType.name().toLowerCase() + ":" + username;
    }

}
